package damngoodcoffee.smart;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

import com.google.inject.Inject;

import damngoodcoffee.smart.commands.Command;
import damngoodcoffee.smart.interpreters.Interpreter;
import damngoodcoffee.smart.interpreters.InterpreterException;
import damngoodcoffee.smart.tags.EndTag;
import damngoodcoffee.smart.tags.StartTag;

public class SmartContentHandlerImpl implements SmartContentHandler {
    private List<Interpreter> interpreters;
    private Interpreter current = null;
    private List<Command> commands = new ArrayList<Command>();

    @Inject
    public SmartContentHandlerImpl(List<Interpreter> interpreters) {
	super();
	this.interpreters = interpreters;
    }

    public List<Command> getCommands() {
	return commands;
    }

    public void reset() {
	commands.clear();
    }

    public void characters(char[] ch, int start, int length)
	    throws SAXException {
	if (current != null) {
	    current.interpret(String.copyValueOf(ch, start, length));
	}
    }

    public void endElement(String uri, String localName, String name)
	    throws SAXException {
	if (current != null) {
	    EndTag t = new EndTag(localName, uri, name);
	    if (current.canInterpret(t)) {
		commands.add(current.getCommand());
		current = null;
	    } else {
		try {
		    current.interpret(t);
		} catch (InterpreterException e) {
		    throw new SAXException(e);
		}
	    }
	}
    }

    public void startElement(String uri, String localName, String qName,
	    Attributes atts) throws SAXException {
	try {

	    StartTag tag = new StartTag(localName, uri, qName, atts);
	    if (current != null) {
		current.interpret(tag);
	    } else {
		for (Interpreter i : interpreters) {
		    if (i.canInterpret(tag)) {
			i.interpret(tag);
			current = i;
			break;
		    }
		}
	    }
	} catch (Exception e) {
	    throw new SAXException(e);
	}
    }

    public void endDocument() throws SAXException {

    }

    public void endPrefixMapping(String prefix) throws SAXException {

    }

    public void ignorableWhitespace(char[] ch, int start, int length)
	    throws SAXException {

    }

    public void processingInstruction(String target, String data)
	    throws SAXException {

    }

    public void setDocumentLocator(Locator locator) {

    }

    public void skippedEntity(String name) throws SAXException {

    }

    public void startDocument() throws SAXException {

    }

    public void startPrefixMapping(String prefix, String uri)
	    throws SAXException {

    }
}
